home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BUG 1
/
BUGCD1996_0708.ISO
/
mac
/
Systemski dodaci
/
Chooser RDEVs (printer drivers)
/
Print2Pict 3.71
/
Sourcesƒ
/
P2PX⁄PICS.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-27
|
14KB
|
658 lines
/*====================
Print to PICS. ⌐ B.Raoult 1992
This file contains an example of a Print2Pict 3.0 extension.
It saves printed pages in a PICS file.
====================*/
#include "P2PX.h"
#include "tools.h"
#ifndef __MEMORY__
# include <Memory.h>
#endif
#ifndef __RESOURCES__
# include <Resources.h>
#endif
#ifndef __ERRORS__
# include <Errors.h>
#endif
#ifndef __QUICKDRAW__
# include <Quickdraw.h>
#endif
#ifndef __TOOLUTILS__
# include <ToolUtils.h>
#endif
#ifndef __A4STUFF__
# include <A4Stuff.h>
#endif
#define TRUE true
#define FALSE false
#define OPTS 'OPTS' /* Type of our options resource */
#define OPTS_ID 128 /* ID of our options resource */
#define SPEED 2 /* Frames/Seconds input field in the options dialog */
#define DELETE 3 /* Frames/Seconds input field in the options dialog */
#define MOVIE 4
#define FIRST_FRAME 128
#define LAST_FRAME 163
/*=======
Prototypes
=======*/
OSErr GetFlags(P2PXPtr arg);
OSErr DoInit(P2PXPtr arg);
OSErr DoEnd(P2PXPtr arg);
OSErr DoPutPage(P2PXPtr arg);
OSErr DoOptOpen(P2PXPtr arg);
OSErr DoOptEvent(P2PXPtr arg);
OSErr DoOptItem(P2PXPtr arg);
OSErr DoOptDone(P2PXPtr arg);
/*=======
Structure of INFO resource used in PICS files
=======*/
typedef struct {
short color; /* Color picture */
short depth; /* Depth of picture */
short speed; /* Frames/seconds */
short version; /* version */
OSType creator; /* creator */
long maxsize; /* size of largest picture */
} Infos, *PInfos, **HInfos;
/*=======
Private data
========*/
typedef struct {
short resfile; /* reference number of the PICS file */
short count; /* current image number */
HInfos info; /* Handle to info resource */
FSSpec fspec; /* Specs of the PICS file */
} Globals, *PGlobals, **HGlobals;
/*========
Our options
========*/
typedef struct {
short speed; /* Frames/seconds */
Boolean remove; /* Delete file if the user aborts the job */
} Opts, *POpts, **HOpts;
/*========
Data for animation
========*/
typedef struct {
short frame; /* Current frame */
long last; /* last time we draw a frame */
Boolean ready; /* ready after first update */
Boolean color; /* plot 'cicn' */
Rect box; /* Where to draw the frames */
long speed; /* Speed in 60th of seconds */
} Anim, *PAnim, **HAnim;
/*=======
Usefull macro to access our globals
========*/
#define G (**((HGlobals)(arg->data)))
#define A (**((HAnim)(arg->data)))
#define O (**o)
#define I (**info)
/*======================================================================================
This is the entry point of the code resource.
It simply dispatches the calls to the proper routine
======================================================================================*/
pascal OSErr main(int msg,P2PXPtr arg)
{
int ret = noErr;
EnterCodeResource();
switch (msg)
{
case kGetFlagsMsg:
ret = GetFlags(arg);
break;
case kInitMsg:
ret = DoInit(arg);
break;
case kEndMsg:
ret = DoEnd(arg);
break;
case kPutPageMsg:
ret = DoPutPage(arg);
break;
case kOptOpenMsg:
ret = DoOptOpen(arg);
break;
case kOptEventMsg:
ret = DoOptEvent(arg);
break;
case kOptItemMsg:
ret = DoOptItem(arg);
break;
case kOptDoneMsg:
ret = DoOptDone(arg);
break;
}
ExitCodeResource();
return ret;
}
/*======================================================================================
Get flags of the code resource.
- It can be called at ANY TIME.
- Most of the fields of the parameters will not be valid.
However, unintialized fields will contain nulls.
- Note that you can later change the values of the flags
in any other calls.
======================================================================================*/
OSErr GetFlags(P2PXPtr arg)
{
arg->flags =
kCanPreview + /* Preview is OK */
kEnvironmentOk + /* We can run on all Macs */
kWantFileNames + /* Wants the file names to save pages */
kHasOwnOptions ; /* We have some options */
return noErr;
}
/*======================================================================================
Called when the application calls PrOpenDoc().
We allocate the handles needed for our globals.
======================================================================================*/
OSErr DoInit(P2PXPtr arg)
{
HInfos info;
HOpts o;
/* Allocate some space four our globals */
if(!(arg->data = NewHandleClear(sizeof(Globals))))
return iMemFullErr;
/* Allocate some space for the INFO structure */
if(!(info = (HInfos)NewHandleClear(sizeof(Infos))))
return iMemFullErr;
/* Get our options */
if(!(o = (HOpts)GetResource(OPTS,OPTS_ID)))
return ResError();
G.resfile = -1; /* The PICS file is not yet opened */
G.count = 128; /* PICT resources start from 128 in a PICS file */
G.info = info; /* Save the INFO structure */
I.maxsize = 0; /* No pictures yet */
I.creator = arg->creator; /* Use the creator chosen by the user */
I.speed = O.speed; /* Use the speed chosen by the use */
return noErr; /* All OK... */
}
/*======================================================================================
End of print. Called from PrOpenDoc() if everything OK.
Can be called at any time if something went wrong, so
check if the private data is valid.
======================================================================================*/
OSErr DoEnd(P2PXPtr arg)
{
int save = CurResFile(); /* Save the current resource file */
OSErr retCode = noErr; /* be optimistic */
HOpts o = (HOpts)GetResource(OPTS,OPTS_ID); /* Get our options record */
Boolean ok = TRUE; /* If not, remove the file */
if(arg->data) /* Did we have memory ? */
{
HInfos info = G.info; /* Recover the INFO structure */
if(G.resfile != -1) /* Did we open any files ? */
{
UseResFile(G.resfile);
if((arg->error == noErr) && info)
{
/* Add the INFO resource to the PICS file, check for error */
AddResource ((Handle) info,'INFO',128,"\p"); retCode = retCode?retCode:ResError();
WriteResource((Handle) info); retCode = retCode?retCode:ResError();
UpdateResFile(G.resfile); retCode = retCode?retCode:ResError();
}
if(retCode != noErr)
ok = FALSE;
}
CloseResFile(G.resfile);
/* Now let's do some clean up */
if(info)
DisposHandle((Handle) info);
/* If an error was reported, we need to remove the file */
if(arg->error != iPrAbort && arg->error != noErr)
ok = FALSE;
/* If this error is iPrAbort (user cancel) remove the file
according to the options */
if(o && O.remove)
if(arg->error == iPrAbort)
ok = FALSE;
/* If something went wrong, don't leave incomplete files around */
if(!ok)
FSpDelete(&arg->fspec);
DisposHandle(arg->data);
}
/* Restore current resource file */
UseResFile(save);
return retCode;
}
/*======================================================================================
Process a page. Called when the application calls PrClosePage().
Create the PICS file if it is the first time in.
Add the picture as a PICT resource.
======================================================================================*/
OSErr DoPutPage(P2PXPtr arg)
{
int save = CurResFile();
OSErr retCode = noErr;
HInfos info;
/* No luck... */
if(!(arg->data))
return -1;
if(!(arg->pict))
return -1;
info = G.info;
/* First time in */
if(G.resfile == -1)
{
/* Delete previous file if any */
if( (retCode = FSpDelete(&arg->fspec)) != noErr)
if(retCode != fnfErr)
return retCode;
/* Create the file, giving it the right Creator and File type.*/
FSpCreateResFile(&arg->fspec, arg->creator, 'PICS',arg->script);
if ((retCode = ResError()) != noErr )
return retCode;
/* Save the file spec if we need to remove it later */
G.fspec = arg->fspec;
/* Open the resoure file */
G.resfile = FSpOpenResFile(&arg->fspec,fsRdWrPerm);
if(G.resfile == -1)
return ResError();
/* We don't want any more file names */
arg->flags &= ~kWantFileNames;
/* Fill the rest of the INFO structure */
/* Are the PICTs in color ? */
I.color = arg->color;
/* If yes, get the depth of the printing port */
if(arg->color)
{
PixMapHandle pix = ((CGrafPtr)(arg->port))->portPixMap;
I.depth = (**pix).pixelSize;
}
else
I.depth = 1;
}
/* Now save the current page as a PICT resource */
UseResFile(G.resfile);
AddResource((Handle) arg->pict,'PICT',(G.count)++,"\p"); retCode = retCode?retCode:ResError();
SetResAttrs((Handle) arg->pict,resPurgeable); retCode = retCode?retCode:ResError();
ChangedResource((Handle) arg->pict); retCode = retCode?retCode:ResError();
WriteResource((Handle) arg->pict); retCode = retCode?retCode:ResError();
UpdateResFile(G.resfile); retCode = retCode?retCode:ResError();
/* Detache it so Print2Pict can kill it */
DetachResource((Handle) arg->pict);
/* Update maxsize in INFO structure */
if(GetHandleSize((Handle) arg->pict)>I.maxsize)
I.maxsize = GetHandleSize((Handle) arg->pict);
/* Restore current resource file */
UseResFile(save);
return retCode;
}
/*======================================================================================
Initialize the options dialog. Allocate some memory for the animation,
initialize the dialog items.
======================================================================================*/
OSErr DoOptOpen(P2PXPtr arg)
{
HOpts o = (HOpts)GetResource(OPTS,OPTS_ID); /* Get our options record */
HAnim a;
/* Something went wrong */
if(!o)
return ResError();
/* Set the frames/seconds text field */
if(O.speed <1 )
O.speed = 1;
/* Initalize the dialog items, Remember to skip the Print2Pict items */
Long2Dialog(arg->dlog,arg->skip + SPEED,(long)O.speed);
SetCheck(arg->dlog,arg->skip + DELETE,O.remove);
/* Allocate some private storage for the animation */
a = (HAnim)NewHandleClear(sizeof(Anim));
/* No big deal if not enough memory */
if(a)
{
/* Store the handle in the parameter block */
arg->data = (Handle)a;
/* Save the rectangle for the animation */
A.box = GetItemR(arg->dlog,arg->skip + MOVIE);
A.frame = FIRST_FRAME;
A.speed = 60 / O.speed; /* Time between frams in 60th of seconds */
A.color = HasColor(); /* Color QuickDraw is there... */
}
return noErr;
}
/*======================================================================================
Called from the ModalDialog filter procedure. We handle use the null events
to run the animation.
======================================================================================*/
OSErr DoOptEvent(P2PXPtr arg)
{
Rect r;
if(arg->data)
{
switch(arg->event->what)
{
case updateEvt:
if(arg->event->message == (long)arg->dlog)
{
/* wait first update before starting the animation */
A.ready = TRUE;
/* Draw a frame around the rectangle */
r = A.box;
InsetRect(&r,-1,-1);
FrameRect(&r);
}
break;
case nullEvent:
if(A.ready)
{
long now = TickCount();
Rect r;
CIconHandle h;
/* If the time is elapsed */
if( now-A.last >= A.speed)
{
A.last = now;
r= A.box;
/* Plot cicn if ColorQD is available, otherwise plot ICON */
if(A.color)
{
h = GetCIcon(A.frame);
PlotCIcon(&r,h);
DisposCIcon(h);
}
else
PlotIcon(&r,GetIcon(A.frame));
/* Move to next frame */
A.frame++;
if(A.frame>LAST_FRAME)
A.frame = FIRST_FRAME;
}
}
break;
}
}
return noErr;
}
/*======================================================================================
Called with the item returned by ModalDialog.
======================================================================================*/
OSErr DoOptItem(P2PXPtr arg)
{
long speed;
switch(arg->item - arg->skip)
{
/* Click in the "delete" checkbox */
case DELETE:
ClickCheck(arg->dlog,arg->item);
break;
/* The "speed" text field as been modified */
case SPEED:
speed = Dialog2Long(arg->dlog,arg->item);
if(speed<1)
speed = 1;
/* Change the speed of the animation with the new value */
if(arg->data)
A.speed = 60/speed;
break;
}
return noErr;
}
/*======================================================================================
End of option dialog. Release use memory and save the changes.
======================================================================================*/
OSErr DoOptDone(P2PXPtr arg)
{
HOpts o = (HOpts)GetResource(OPTS,OPTS_ID); /* Get our options record */
long newspeed;
Boolean remove;
OSErr retCode = noErr;
/* Something went wrong */
if(!o)
{
if(arg->data)
DisposHandle(arg->data);
return ResError();
}
/* Get the new values */
newspeed = Dialog2Long(arg->dlog,arg->skip + SPEED);
remove = GetCheck(arg->dlog,arg->skip + DELETE);
/* If the user changed the value, update the record */
if(O.speed != newspeed || O.remove != remove)
{
if(newspeed <1 )
newspeed = 1;
O.speed = newspeed;
O.remove = remove;
ChangedResource((Handle) o);
WriteResource((Handle) o);
UpdateResFile(HomeResFile((Handle) o));
retCode = ResError();
}
/* Realease used memory */
if(arg->data)
{
/* Because we draw outside of an item, we must clear it ourselves */
Rect r = A.box;
InsetRect(&r,-1,-1);
EraseRect(&r);
DisposHandle(arg->data);
}
return retCode;
}